package band.wukong.practice.netty.sample.heartbeat.client;

import band.wukong.practice.netty.Env;
import band.wukong.practice.netty.sample.heartbeat.common.CustomHeartbeatHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.Random;

/**
 * Desc:
 * author: wukonggg@139.com
 */
public class Client {

    private static final Logger logger;
    static {
        Env.assemblingLog4j2ConfFile();
        logger = LogManager.getLogger();
    }

    public static void main(String[] args) throws Exception {
        NioEventLoopGroup workGroup = new NioEventLoopGroup(4);
        Random random = new Random(System.currentTimeMillis());
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap
                    .group(workGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline p = socketChannel.pipeline();
                            // IdleStateHandler是心跳机制的核心。 我们为客户端端设置了读写 idle 超时, 时间间隔是5s,
                            // 即如果客户端在间隔 5s 后都没有收到服务器的消息或向服务器发送消息, 则产生 ALL_IDLE 事件.
                            p.addLast(new IdleStateHandler(0, 0, 5));
                            // LengthFieldBasedFrameDecoder负责解析 TCP 报文
                            p.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 4, -4, 0));
                            // ClientHandler继承于 CustomHeartbeatHandler, 是我们处理业务逻辑部分.
                            p.addLast(new ClientHandler());
                        }
                    });

            Channel ch = bootstrap.remoteAddress(Env.HOST, Env.PORT).connect().sync().channel();
            for (int i = 0; i < 10; i++) {
                String content = "client msg " + i;
                ByteBuf buf = ch.alloc().buffer();
                buf.writeInt(5 + content.getBytes().length);
                buf.writeByte(CustomHeartbeatHandler.CUSTOM_MSG);
                buf.writeBytes(content.getBytes());
                ch.writeAndFlush(buf);

                Thread.sleep(random.nextInt(20000));
            }
        } finally {
            workGroup.shutdownGracefully();
        }
    }
}
